package com.kuaimacode.kframework.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;

@Slf4j
@ControllerAdvice
class ExceptionHandlerControllerAdvice {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<?> resourceNotFoundExceptionHandler(HttpServletRequest request, ResourceNotFoundException e) {
        logError(request, e);

        return ResponseEntity
                .status(HttpStatus.NOT_FOUND)
                .body(new Error()
                        .setCode(String.valueOf(ErrorCode.RESOURCE_NOT_FOUND_ERROR))
                        .setMessage(e.getMessage()));
    }

    @ExceptionHandler(ParameterIllegalException.class)
    public ResponseEntity<?> parameterIllegalExceptionHandler(HttpServletRequest request, ParameterIllegalException e) {
        logError(request, e);

        return ResponseEntity
                .status(HttpStatus.BAD_REQUEST)
                .body(new Error()
                        .setCode(String.valueOf(ErrorCode.PARAMETER_ILLEGAL_ERROR))
                        .setMessage("An invalid value was specified for one of the query parameters in the request URL."));
    }

    @ExceptionHandler(ServerInternalErrorException.class)
    public ResponseEntity<?> serverInternalErrorExceptionHandler(HttpServletRequest request, ServerInternalErrorException e) {
        log.error("业务异常，code: {}, message: {}", e.getCode(), e.getMessage(), e);

        return ResponseEntity
                .status(HttpStatus.OK)
                .body(new Error()
                        .setCode(e.getCode())
                        .setMessage(e.getMessage()));
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<?> parameterIllegalExceptionHandler(HttpServletRequest request, MethodArgumentNotValidException e) {
        logError(request, e);

        String errorMsg = (e.getBindingResult().getFieldError() == null ? "An invalid value was specified for one of the query parameters in the request URL." :
                e.getBindingResult().getFieldError().getDefaultMessage());
        return ResponseEntity
                .status(HttpStatus.BAD_REQUEST)
                .body(new Error()
                        .setCode(String.valueOf(ErrorCode.PARAMETER_ILLEGAL_ERROR))
                        .setMessage(errorMsg));
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<?> exceptionHandler(HttpServletRequest request, Exception e) {
        logError(request, e);

        return ResponseEntity
                .status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(new Error()
                        .setCode(String.valueOf(ErrorCode.SERVER_INTERNAL_ERROR))
                        .setMessage("The server met an unexpected error. Please contact administrators."));
    }

    private void logError(HttpServletRequest request, Exception e) {
        log.error("[URI: " + request.getRequestURI() + "]", e);
    }

}
